""" _*_ coding : utf-8 _*_
 @Time: 2025/8/27 21:12
 @Author : 虎
 @File : config
 @Project : education
"""
# apps/routers/UsersManger/config.py
# apps/routers/UsersManger/jwt_utils.py
from datetime import datetime, timedelta
import jwt
import os
from fastapi import HTTPException, status, Depends, Request
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
import secrets
import logging

# 设置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)


# 直接在工具类中定义配置
class JWTConfig:
    # 从环境变量获取或使用默认值 - 确保密钥足够长
    SECRET_KEY = os.getenv("JWT_SECRET_KEY", "your-strong-secret-key-here-make-it-32-chars")
    ALGORITHM = os.getenv("JWT_ALGORITHM", "HS256")
    # 设置token过期时间为30分钟
    ACCESS_TOKEN_EXPIRE_MINUTES = int(os.getenv("JWT_EXPIRE_MINUTES", "30"))

    # 添加方法检查配置
    @classmethod
    def check_config(cls):
        config_info = {
            "secret_key_length": len(cls.SECRET_KEY),
            "algorithm": cls.ALGORITHM,
            "expire_minutes": cls.ACCESS_TOKEN_EXPIRE_MINUTES
        }
        logger.info(f"JWT配置: {config_info}")
        return config_info


# 初始化时检查配置
JWTConfig.check_config()

security = HTTPBearer(auto_error=False)


class JWTUtils:
    @staticmethod
    def create_access_token(data: dict, expires_delta: timedelta = None) -> str:
        to_encode = data.copy()
        if expires_delta:
            expire = datetime.utcnow() + expires_delta
        else:
            expire = datetime.utcnow() + timedelta(
                minutes=JWTConfig.ACCESS_TOKEN_EXPIRE_MINUTES
            )

        to_encode.update({"exp": expire})

        # 添加调试信息
        logger.info(f"生成token的数据: {to_encode}")
        logger.info(f"使用的密钥长度: {len(JWTConfig.SECRET_KEY)}")
        logger.info(f"使用的算法: {JWTConfig.ALGORITHM}")

        try:
            token = jwt.encode(
                to_encode,
                JWTConfig.SECRET_KEY,
                algorithm=JWTConfig.ALGORITHM
            )
            logger.info(f"成功生成token: {token[:50]}...")  # 只显示前50个字符
            return token
        except Exception as e:
            logger.error(f"生成token失败: {str(e)}")
            raise

    @staticmethod
    def decode_token(token: str) -> dict:
        try:
            logger.info(f"尝试解码token: {token[:50]}...")  # 只显示前50个字符
            logger.info(f"使用的密钥: {JWTConfig.SECRET_KEY[:10]}...")  # 只显示前10个字符
            logger.info(f"使用的算法: {JWTConfig.ALGORITHM}")

            payload = jwt.decode(
                token,
                JWTConfig.SECRET_KEY,
                algorithms=[JWTConfig.ALGORITHM]
            )
            logger.info(f"解码成功: {payload}")
            return payload
        except jwt.ExpiredSignatureError:
            logger.warning("Token已过期")
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail="Token已过期"
            )
        except jwt.InvalidTokenError as e:
            logger.error(f"无效Token错误: {str(e)}")
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail="无效的Token"
            )
        except Exception as e:
            logger.error(f"Token解码异常: {str(e)}")
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail=f"Token验证失败: {str(e)}"
            )


async def get_current_user(credentials: HTTPAuthorizationCredentials = Depends(security)):
    if not credentials:
        logger.warning("未提供认证凭证")
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="未提供认证凭证",
            headers={"WWW-Authenticate": "Bearer"},
        )

    token = credentials.credentials
    logger.info(f"接收到token: {token[:50]}...")

    try:
        payload = JWTUtils.decode_token(token)
        return payload
    except HTTPException as he:
        logger.error(f"HTTP异常: {he.detail}")
        raise
    except Exception as e:
        logger.error(f"获取用户信息异常: {str(e)}")
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail=f"认证失败: {str(e)}"
        )


# 添加调试端点
async def debug_jwt_config():
    """返回JWT配置信息"""
    return {
        "jwt_config": JWTConfig.check_config(),
        "current_time": datetime.utcnow().isoformat()
    }


# 添加token验证端点
async def verify_token_directly(token: str):
    """直接验证token"""
    try:
        payload = JWTUtils.decode_token(token)
        return {
            "valid": True,
            "payload": payload,
            "role": payload.get("role"),
            "expires_at": datetime.fromtimestamp(payload.get("exp")).isoformat() if payload.get("exp") else None
        }
    except Exception as e:
        return {
            "valid": False,
            "error": str(e)
        }

